home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / SmallEiffel 0.3.3 / SmallEiffel PPC / lib_std / collection.e < prev    next >
Encoding:
Text File  |  1996-06-13  |  7.7 KB  |  406 lines  |  [TEXT/EDIT]

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. deferred class COLLECTION[E]
  5. -- 
  6. -- Such a collection is a traversable one using INTEGER indexing
  7. -- from `lower' to `upper'.
  8. -- Standard ARRAY[E] inherit from COLLECTION[E].
  9. --
  10.  
  11. inherit
  12.    ANY
  13.       undefine copy 
  14.       redefine is_equal, fill_tagged_out_memory
  15.       end;
  16.  
  17. feature -- Indexing :
  18.  
  19.    lower: INTEGER is
  20.      -- Lower index bound.
  21.       deferred
  22.       end;
  23.  
  24.    upper: INTEGER is
  25.      -- Upper index bound.
  26.       deferred
  27.       end;
  28.  
  29.    valid_index(index: INTEGER): BOOLEAN is
  30.      -- True when `index' is valid (ie inside actual bounds).
  31.       do
  32.      Result := lower <= index and then index <= upper;
  33.       ensure      
  34.      Result = (lower <= index and index <= upper);
  35.       end;
  36.  
  37.    count: INTEGER is
  38.      -- Length of index interval.
  39.       do
  40.      Result := upper - lower + 1;
  41.       end;
  42.  
  43.    empty: BOOLEAN is
  44.      -- Is collection empty?
  45.       do
  46.      Result := (count = 0);
  47.       end;
  48.  
  49. feature -- Accessing :
  50.  
  51.    infix "@", item(index: INTEGER): E is
  52.      -- Item at position `index'.
  53.       require
  54.      inside_bounds: valid_index(index)
  55.       deferred
  56.       end;
  57.  
  58.    first: like item is
  59.       require
  60.      count >= 1
  61.       do
  62.      Result := item(lower);
  63.       end;
  64.    
  65.    last: like item is
  66.       require
  67.      count >= 1
  68.       do
  69.      Result := item(upper);
  70.       end;
  71.  
  72. feature -- Writing :
  73.  
  74.    put(element: like item; index: INTEGER) is
  75.      -- Put `element' at position `index'.
  76.       require
  77.      valid_index(index)
  78.       deferred
  79.       ensure
  80.      item(index) = element
  81.       end;
  82.  
  83.    swap(i1, i2: INTEGER) is
  84.       require
  85.      valid_index(i1);
  86.      valid_index(i2);
  87.       local
  88.      tmp: like item;
  89.       do
  90.      tmp := item(i1);
  91.      put(item(i2),i1);
  92.      put(tmp,i2);
  93.       ensure
  94.      item(i1) = old item(i2);
  95.      item(i2) = old item(i1);
  96.       end;
  97.         
  98.    set_all_with(v: like item) is
  99.      -- Set all item with `v'.
  100.       local
  101.      i: INTEGER;
  102.       do
  103.      from  
  104.         i := upper;
  105.      until
  106.         i < lower
  107.      loop
  108.         put(v,i);
  109.         i := i - 1;
  110.      end;      
  111.       ensure
  112.      count = old count
  113.       end;
  114.    
  115.    set_slice_with(v: like item; lower_index, upper_index: INTEGER) is
  116.      -- Set all item with `v'.
  117.       require
  118.      lower_index <= upper_index;
  119.      valid_index(lower_index);
  120.      valid_index(upper_index);
  121.       local
  122.      i: INTEGER;
  123.       do
  124.      from  
  125.         i := lower_index;
  126.      until
  127.         i > upper_index
  128.      loop
  129.         put(v,i);
  130.         i := i + 1;
  131.      end;      
  132.       ensure
  133.      count = old count
  134.       end;
  135.    
  136.     clear_all is
  137.      -- Set all items to default values.
  138.       local
  139.      value: like item;
  140.       do
  141.      set_all_with(value);
  142.       ensure
  143.      count = old count;
  144.       end;
  145.    
  146. feature -- Looking and Searching :
  147.  
  148.    has(x: like item): BOOLEAN is
  149.      -- Look for `x' using `equal'.
  150.       do
  151.      Result := (index_of(x) /= upper + 1);
  152.       end;
  153.    
  154.    fast_has(x: like item): BOOLEAN is
  155.      -- Same as `has' but use `='.
  156.       do
  157.      Result := (fast_index_of(x) /= upper + 1);
  158.       end;
  159.    
  160.    index_of(x: like item): INTEGER is
  161.      -- Give the index of the first occurrence of `x' using `equal'.
  162.      -- Answer `upper + 1' when `x' is not inside.
  163.       do
  164.      from  
  165.         Result := lower;
  166.      until
  167.         (Result > upper) or else equal_like(x,item(Result))
  168.      loop
  169.         Result := Result + 1;
  170.      end;
  171.       ensure
  172.      lower <= Result;
  173.      Result <= upper + 1;
  174.      Result <= upper implies equal(x,item(Result));
  175.       end;
  176.    
  177.    fast_index_of(x: like item): INTEGER is
  178.      -- Same as `index_of' but use `=' for comparison.
  179.       do
  180.      from  
  181.         Result := lower;
  182.      until
  183.         (Result > upper) or else x = item(Result)
  184.      loop
  185.         Result := Result + 1;
  186.      end;
  187.       ensure
  188.      lower <= Result;
  189.      Result <= upper + 1;
  190.      Result <= upper implies x = item(Result);
  191.       end;
  192.    
  193. feature -- Looking and comparison :
  194.  
  195.    is_equal(other: like Current): BOOLEAN is
  196.      -- Use `equal' to compare elements. 
  197.       local
  198.      i: INTEGER;
  199.      e1, e2: like item;
  200.       do
  201.      if Current = other then
  202.         Result := true;
  203.      elseif lower = other.lower and then 
  204.         upper = other.upper then
  205.         from
  206.            Result := true;
  207.            i := lower;
  208.         until
  209.            i > upper or not Result
  210.         loop
  211.            Result := equal_like(item(i),other.item(i));
  212.            i := i + 1;
  213.         end;        
  214.      end;
  215.       end;
  216.  
  217.    all_cleared: BOOLEAN is
  218.      -- Are all items set to default values?
  219.       local
  220.      value: like item;
  221.      i: INTEGER;
  222.       do
  223.      from  
  224.         Result := true;
  225.         i := lower;
  226.      until
  227.         not Result or else i > upper
  228.      loop
  229.         Result := value = item(i);
  230.         i := i + 1;
  231.      end;
  232.       end;
  233.  
  234.    nb_occurrences(elt: like item): INTEGER is
  235.      -- Number of occurrences using `equal'.
  236.      -- See also `fast_nb_occurrences' to chose
  237.      -- the apropriate one.
  238.       local
  239.      i: INTEGER;
  240.       do
  241.      from  
  242.         i := lower;
  243.      until
  244.         i > upper
  245.      loop
  246.         if equal_like(elt,item(i)) then
  247.            Result := Result + 1;
  248.         end;
  249.         i := i + 1;
  250.      end;
  251.       ensure
  252.      Result >= 0;
  253.       end;
  254.       
  255.    fast_nb_occurrences(elt: like item): INTEGER is
  256.      -- Number of occurrences using `='.
  257.       local
  258.      i: INTEGER;
  259.       do
  260.      from  
  261.         i := lower;
  262.      until
  263.         i > upper
  264.      loop
  265.         if elt = item(i) then
  266.            Result := Result + 1;
  267.         end;
  268.         i := i + 1;
  269.      end;
  270.       ensure
  271.      Result >= 0;
  272.       end;
  273.       
  274. feature -- Object Printing :
  275.  
  276.    fill_tagged_out_memory is
  277.       local
  278.      i: INTEGER;
  279.      v: like item;
  280.       do
  281.      tagged_out_memory.append("lower: "); 
  282.      lower.append_in(tagged_out_memory);
  283.      tagged_out_memory.append(" upper: "); 
  284.      upper.append_in(tagged_out_memory);
  285.      tagged_out_memory.append(" [");
  286.      from  
  287.         i := lower;
  288.      until
  289.         i > upper or else tagged_out_memory.count > 2048
  290.      loop
  291.         v := item(i);
  292.         if v = Void then
  293.            tagged_out_memory.append("Void");
  294.         else
  295.            v.out_in_tagged_out_memory;
  296.         end;
  297.         if i < upper then
  298.            tagged_out_memory.extend(' ');
  299.         end;
  300.         i := i + 1;
  301.      end;
  302.      if i <= upper then
  303.         tagged_out_memory.append(" ..."); 
  304.      end;
  305.      tagged_out_memory.extend(']'); 
  306.       end;
  307.  
  308. feature -- Other Features :
  309.  
  310.    clear is
  311.      -- Discard all items.
  312.       deferred
  313.       ensure
  314.      empty;
  315.       end;
  316.  
  317.    replace_all(x, r: like item) is
  318.       local
  319.      i: INTEGER;
  320.       do
  321.      from
  322.         i := lower;
  323.      until 
  324.         i > upper
  325.      loop
  326.         if equal_like(item(i),x) then
  327.            put(r,i);
  328.         end;
  329.         i := i + 1;
  330.      end;
  331.       end;
  332.    
  333.    fast_replace_all(x, r: like item) is
  334.       local
  335.      i: INTEGER;
  336.       do
  337.      from 
  338.         i := lower;
  339.      until
  340.         i > upper
  341.      loop
  342.         if item(i) = x then
  343.            put(r, i);
  344.         end;
  345.         i := i + 1;
  346.      end;
  347.       end;
  348.  
  349.    move(lower_index, upper_index, distance: INTEGER) is
  350.      -- Move Range `lower_index' .. `upper_index' by `distance' 
  351.      -- positions. Negative distance moves towards lower indices.
  352.      -- Free places get default values.
  353.       require
  354.      lower_index <= upper_index;
  355.      valid_index(lower_index);
  356.      valid_index(lower_index + distance);
  357.      valid_index(upper_index);
  358.      valid_index(upper_index + distance);
  359.       local
  360.      default_value: like item;
  361.      i: INTEGER;
  362.       do
  363.      if distance < 0 then
  364.         from  
  365.            i := lower_index;
  366.         until
  367.            i > upper_index
  368.         loop
  369.            put(item(i),i + distance);
  370.            put(default_value,i);
  371.            i := i + 1;
  372.         end;
  373.      elseif distance > 0 then
  374.         from  
  375.            i := upper_index;
  376.         until
  377.            i < lower_index
  378.         loop
  379.            put(item(i),i + distance);
  380.            put(default_value,i);
  381.            i := i - 1;
  382.         end;
  383.      end;
  384.       end;
  385.  
  386. feature {NONE}
  387.  
  388.    equal_like(e1, e2: like item): BOOLEAN is
  389.      -- Note: to avoid calling `equal' :-(
  390.      -- Because SmallEiffel is not yet able to infer 
  391.      -- arguments types.
  392.       do
  393.      if e1.is_basic_expanded_type then
  394.         Result := e1 = e2;
  395.      elseif e1.is_expanded_type then
  396.         Result := e1.is_equal(e2);
  397.      elseif e1 = e2 then
  398.         Result := true;
  399.      elseif e1 = Void or else e2 = Void then
  400.      else
  401.         Result := e1.is_equal(e2);
  402.      end;
  403.       end;
  404.  
  405. end -- COLLECTION
  406.